home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / utility / wzun11sr.zip / MATCH.C < prev    next >
Text File  |  1991-09-27  |  6KB  |  236 lines

  1. /*--------------------------------------------------------------------------
  2.  
  3.   match.c
  4.  
  5.   The match() routine recursively compares a string to a "pattern" (regular
  6.   expression), returning TRUE if a match is found or FALSE if not.  This
  7.   version is specifically for use with unzip.c:  it leaves the case (upper,
  8.   lower, or mixed) of the string alone, but converts any uppercase characters
  9.   in the pattern to lowercase if indicated by the global variable lcflag
  10.   (which is to say, string is assumed to have been converted to lowercase
  11.   already, if such was necessary).
  12.  
  13.   --------------------------------------------------------------------------
  14.  
  15.   Revision history:
  16.  
  17.      Original Author:  Thom Henderson
  18.      Original System V port:  Mike Stump
  19.  
  20.      03/22/87  C. Seaman      enhancements, bug fixes, cleanup
  21.      11/13/89  C. Mascott     adapted for use with unzip
  22.      01/25/90  J. Cowan       made case-insensitive (only for smart toupper())
  23.      03/17/90  D. Kirschbaum  prototypes, other tweaks for Turbo C
  24.      05/18/90  M. O'Carroll   DOS and OS/2 family version
  25.      09/20/90  G. Roelofs     modified for lcflag, moved stuff to header file
  26.  
  27.   --------------------------------------------------------------------------
  28.  
  29.   Copyright, originally from arcmatch.c, version 1.1 (?):
  30.  
  31.      * ARC - Archive utility - ARCMATCH
  32.      *
  33.      * Version 2.17, created on 12/17/85) at 20:32:18
  34.      *
  35.      * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  36.  
  37.   --------------------------------------------------------------------------*/
  38.  
  39.  
  40. #include "unzip.h"
  41.  
  42.  
  43. /*******************/
  44. /*  Match Defines  */
  45. /*******************/
  46.  
  47. #define ASTERISK        '*'     /* The '*' metacharacter */
  48. #define QUESTION        '?'     /* The '?' metacharacter */
  49. #define BACK_SLASH      '\\'    /* The '\' metacharacter */
  50. #define LEFT_BRACKET    '['     /* The '[' metacharacter */
  51. #define RIGHT_BRACKET   ']'     /* The ']' metacharacter */
  52. #define EOS             '\000'  /* end-of-string */
  53.  
  54. #define IS_OCTAL(ch)    (ch >= '0' && ch <= '7')
  55.  
  56.  
  57.  
  58. /********************/
  59. /*  Match Typedefs  */
  60. /********************/
  61.  
  62. typedef short int INT;
  63. typedef short int BOOLEAN;
  64.  
  65.  
  66.  
  67. /*************************************/
  68. /*  Match Local Function Prototypes  */
  69. /*************************************/
  70.  
  71. static BOOLEAN do_list __((register char *string, char *pattern));
  72. static void list_parse __((char **patp, char *lowp, char *highp));
  73. static char nextch __((char **patp));
  74.  
  75.  
  76.  
  77.  
  78.  
  79. /**********************/
  80. /*  Function match()  */
  81. /**********************/
  82.  
  83. int match(string, pattern)
  84. char *string;
  85. char *pattern;
  86. {
  87.     register int ismatch;
  88.  
  89.     ismatch = FALSE;
  90.     switch (*pattern) {
  91.     case ASTERISK:
  92.         pattern++;
  93.         do {
  94.             ismatch = match(string, pattern);
  95.         }
  96.         while (!ismatch && *string++ != EOS);
  97.         break;
  98.     case QUESTION:
  99.         if (*string != EOS)
  100.             ismatch = match(++string, ++pattern);
  101.         break;
  102.     case EOS:
  103.         if (*string == EOS)
  104.             ismatch = TRUE;
  105.         break;
  106.     case LEFT_BRACKET:
  107.         if (*string != EOS)
  108.             ismatch = do_list(string, pattern);
  109.         break;
  110.     case BACK_SLASH:
  111.         pattern++;
  112.     default:
  113. #ifdef OS2
  114.         if (tolower(*string) == tolower(*pattern)) {
  115. #else
  116.         if (*string == ((lcflag && isupper(*pattern)) ? tolower(*pattern) : *pattern)) {
  117. #endif
  118.             string++;
  119.             pattern++;
  120.             ismatch = match(string, pattern);
  121.         } else
  122.             ismatch = FALSE;
  123.         break;
  124.     }
  125.     return (ismatch);
  126. }
  127.  
  128.  
  129.  
  130.  
  131.  
  132. /************************/
  133. /*  Function do_list()  */
  134. /************************/
  135.  
  136. static BOOLEAN do_list(string, pattern)
  137. register char *string;
  138. char *pattern;
  139. {
  140.     register BOOLEAN ismatch;
  141.     register BOOLEAN if_found;
  142.     register BOOLEAN if_not_found;
  143.     auto char lower;
  144.     auto char upper;
  145.  
  146.     pattern++;
  147.     if (*pattern == '!') {
  148.         if_found = FALSE;
  149.         if_not_found = TRUE;
  150.         pattern++;
  151.     } else {
  152.         if_found = TRUE;
  153.         if_not_found = FALSE;
  154.     }
  155.     ismatch = if_not_found;
  156.     while (*pattern != ']' && *pattern != EOS) {
  157.         list_parse(&pattern, &lower, &upper);
  158. #ifdef OS2
  159.         if (tolower(*string) >= tolower(lower) &&
  160.           tolower(*string) <= tolower(upper)) {
  161. #else
  162.         if (*string >= lower && *string <= upper) {
  163. #endif
  164.             ismatch = if_found;
  165.             while (*pattern != ']' && *pattern != EOS)
  166.                 pattern++;
  167.         }
  168.     }
  169.  
  170.     if (*pattern++ != ']') {
  171.         printf("Character class error\n");
  172. #ifdef MSWIN
  173.         return(FALSE);
  174. #else
  175.         exit(1);
  176. #endif
  177.  
  178.     } else if (ismatch)
  179.         ismatch = match(++string, pattern);
  180.  
  181.     return (ismatch);
  182. }
  183.  
  184.  
  185.  
  186.  
  187.  
  188. /***************************/
  189. /*  Function list_parse()  */
  190. /***************************/
  191.  
  192. static void list_parse(patp, lowp, highp)
  193. char **patp;
  194. char *lowp;
  195. char *highp;
  196. {
  197.     *lowp = nextch(patp);
  198.     if (**patp == '-') {
  199.         (*patp)++;
  200.         *highp = nextch(patp);
  201.     } else
  202.         *highp = *lowp;
  203. }
  204.  
  205.  
  206.  
  207.  
  208.  
  209. /***********************/
  210. /*  Function nextch()  */
  211. /***********************/
  212.  
  213. static char nextch(patp)
  214. char **patp;
  215. {
  216.     register char ch;
  217.     register char chsum;
  218.     register INT count;
  219.  
  220.     ch = *(*patp)++;
  221.     if (ch == '\\') {
  222.         ch = *(*patp)++;
  223.         if (IS_OCTAL(ch)) {
  224.             chsum = 0;
  225.             for (count = 0; count < 3 && IS_OCTAL(ch); count++) {
  226.                 chsum *= 8;
  227.                 chsum += ch - '0';
  228.                 ch = *(*patp)++;
  229.             }
  230.             (*patp)--;
  231.             ch = chsum;
  232.         }
  233.     }
  234.     return (ch);
  235. }
  236.